##0000000000000000000000000000000000000000000000000000000000000000000000000000 Paths configs
## message(STATUS "[PATH] CMake binary dir: ${CMAKE_BINARY_DIR}")
set(MY_ROOT_DIR "${CMAKE_SOURCE_DIR}" CACHE PATH "Root directory of this project")
message(STATUS "[PATH] Root directory of this project: ${MY_ROOT_DIR}")
## MY_UPPER_ROOT 是 ROOT dir 往上一层的目录; 通常是 git 仓库根目录
# get_filename_component(MY_UPPER_ROOT ${MY_ROOT_DIR} DIRECTORY CACHE "Totally git repo dir")
set(MY_UPPER_ROOT ${MY_ROOT_DIR} CACHE PATH "Upper root of this project")
message(STATUS "[PATH] Upper root of this project: ${MY_UPPER_ROOT}")
##xxxxxxxxxxxxxxxxxxxxxx
set(MY_COMMON_DIR "${MY_UPPER_ROOT}/src/common" CACHE PATH "common include directory")
set(MY_THIRD_PARTY_HXX "${MY_UPPER_ROOT}/thirdpartyhxx" CACHE PATH "third party head-only libs") # header only 三方库
set(MY_CONAN_RUNTIME_DIR "${CMAKE_BINARY_DIR}/runtime/" CACHE PATH "Conan runtime collection directory")
message(STATUS "[PATH] Conan runtime collection directory: ${MY_CONAN_RUNTIME_DIR}")
set(MY_TESTIO_DIR "${MY_UPPER_ROOT}/testio" CACHE PATH "test io files") # 测试输入输出文件夹
##xxxxxxxxxxxxxxxxxxxxxx 二进制输出目录
# set(MY_PATH_BIN ${CMAKE_BINARY_DIR} CACHE PATH "Binary output directory") # build 结果 output directory
set(MY_PATH_BIN "${MY_ROOT_DIR}/bin" CACHE PATH "Binary output directory")
message(STATUS "[PATH] Binary output directory: ${MY_PATH_BIN}")
# 检查是否为单配置生成器（如 Ninja）或多配置生成器（如 Visual Studio）
if(CMAKE_CONFIGURATION_TYPES)
    # 多配置生成器（如 Visual Studio）
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MY_PATH_BIN})
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MY_PATH_BIN})
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${MY_PATH_BIN})
    message(STATUS "[PATH] Multi-config generator - Output directory: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
else()
    # 单配置生成器（如 Ninja）
    # if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "Release")
    set(OUTPUT_SUBDIR ${CMAKE_BUILD_TYPE})
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${MY_PATH_BIN}/${OUTPUT_SUBDIR}")
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${MY_PATH_BIN}/${OUTPUT_SUBDIR}")
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${MY_PATH_BIN}/${OUTPUT_SUBDIR}")
    message(STATUS "[PATH] Single-config generator - Output directory: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
    # endif()
endif()

##xxxxxxxxxxxxxxxxxxxxxx 自行编译的第三方库
set(MY_THIRD_PARTY "${MY_ROOT_DIR}/thirdparty" CACHE PATH "Third party directory")

##xxxxxxxxxxxxxxxxxxxxxx 日志的输出目录
set(MY_LOG_DIR "${MY_PATH_BIN}/logs" CACHE PATH "Logs directory")

##xxxxxxxxxxxxxxxxxxxxxx dllexport header files dir
set(MY_EXPORTS_DIR "${MY_ROOT_DIR}/export_headers" CACHE PATH "Export headers directory")

##xxxxxxxxxxxxxxxxxxxxxx cmake install dir
set(CMAKE_INSTALL_PREFIX "${MY_ROOT_DIR}/inst-demo" CACHE PATH "Install path" FORCE) # 安装目录, demo
message(STATUS "[PATH] Binary install demo directory: ${CMAKE_INSTALL_PREFIX}")



##000000000000000000000000000000000000000000000000000000000000000000000 C++ CMake 跨平台通用设置, 需要放在 project(xxx) 调用后面
option(MY_ENABLE_CUDA_DEBUG "Enable cuda-gdb for builds" OFF)

##xxxxxxxxxxxxxxxxxxx toolchain configs; IDE 设置
# 让 generator 生成 clangd 需要的 build/compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

##xxxxxxxxxxxxxxxxxxx c++, cuda 语言设置
# option(BUILD_SHARED_LIBS "Build shared libraries" ON)
set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries")
##
find_package(CUDAToolkit REQUIRED)
##
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CXX_STANDARD 17) # C++ 标准
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# set(CMAKE_CXX_EXTENSIONS OFF)
##
set(CMAKE_CUDA_STANDARD 17) # cuda c++17
set(CMAKE_CUDA_STANDARD_REQUIRED ON)

##=============== cuda architectures
# set(CMAKE_CUDA_ARCHITECTURES 75 80 86 87 89 90 100 110 120) # nvidia cuda sample 的设置
# set(CMAKE_CUDA_ARCHITECTURES 86 120)
set(CMAKE_CUDA_ARCHITECTURES 86)
# set(CMAKE_CUDA_ARCHITECTURES native)
message(STATUS "[cuda] CMAKE_CUDA_ARCHITECTURES => ${CMAKE_CUDA_ARCHITECTURES}")
##=============== cuda debug 设置
if(MY_ENABLE_CUDA_DEBUG)
    message(STATUS "[cuda] cuda debug mode")
    set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -G")        # enable cuda-gdb (可能大大降低某些 targets 的性能)
else()
    message(STATUS "[cuda] cuda release mode")
    set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -lineinfo") # add line information to all builds for debug tools (exclusive to -G option)
endif()

##xxxxxxxxxxxxxxxxxxx linux 二进制 属性
# set(CMAKE_SKIP_RPATH TRUE) # 禁用自动RPATH
# set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
set(CMAKE_INSTALL_RPATH "$ORIGIN")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH OFF)

##xxxxxxxxxxxxxxxxxxx CUDA 全局设置
# 设置 CUDA 运行时库为动态链接
# set(CMAKE_CUDA_RUNTIME_LIBRARY Shared)
set(CMAKE_CUDA_RUNTIME_LIBRARY HYBRID)
include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
# cuda 文件单独编译
set(CUDA_SEPARABLE_COMPILATION ON)
set(CUDA_RESOLVE_DEVICE_SYMBOLS ON)


##xxxxxxxxxxxxxxxxxxx 第三方库设置
# fmt::fmt
# 设置FMT_UNICODE=0禁用Unicode支持，避免fmt库中的static_assert错误
# 或者设置为1并确保所有编译器都使用/utf-8选项
add_compile_definitions("FMT_UNICODE=0")

##xxxxxxxxxxxxxxxxxxx MSVC c++ 设置
set(MY_CXX_CMPILE_OPTIONS "")
set(MY_CUDA_CMPILE_OPTIONS "")
if(MSVC)
    message(STATUS ">>>[my] Setting MSVC cl, link")

    # 1. 强制所有 C/C++ 目标使用动态运行时
    # set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
    message(STATUS "[my] MSVC compiler: ${CMAKE_CXX_COMPILER}")
    ##  "/fp:fast" "/O2" "/GL"
    set(MY_CXX_CMPL_OPTS_MSVC "/utf-8" "/EHsc" "/Zc:__cplusplus" "/permissive-" "/fp:fast")
    list(JOIN MY_CXX_CMPL_OPTS_MSVC " " MY_CXX_CMPILE_OPTIONS)
    # message(STATUS "[my] MY_CXX_CMPILE_OPTIONS =>  ${MY_CXX_CMPILE_OPTIONS}")

    list(JOIN MY_CXX_CMPL_OPTS_MSVC "," MY_CUDA_CMPILE_OPTIONS)
    set(MY_CUDA_CMPILE_OPTIONS -Xcompiler="${MY_CUDA_CMPILE_OPTIONS}")
    # message(STATUS "[my] MY_CUDA_CMPILE_OPTIONS => ${MY_CUDA_CMPILE_OPTIONS}")
endif()


# add_compile_options("$<$<AND:$<CXX_COMPILER_ID:MSVC>,$<COMPILE_LANGUAGE:CXX>>:${MY_CXX_CMPILE_OPTIONS}>")
# 可选的：为C++代码禁用特定警告
# add_compile_options("$<$<AND:$<CXX_COMPILER_ID:MSVC>,$<COMPILE_LANGUAGE:CXX>>:/wd4819>")

# get_property(MY_DBG_DIR_COMP_OPTS DIRECTORY ${MY_ROOT_DIR} PROPERTY COMPILE_OPTIONS)
# message(STATUS "[my] MY_DBG_DIR_COMP_OPTS => ${MY_DBG_DIR_COMP_OPTS}")

##xxxxxxxxxxxxxxxxxxx Linux GCC 编译选项
set(MY_COMPILER_ID "${CMAKE_CXX_COMPILER_ID}")
if(NOT CMAKE_CXX_COMPILER_ID)
    set(MY_COMPILER_ID "${CMAKE_C_COMPILER_ID}")
endif()

set(MY_CXX_CMPILE_OPTIONS "")
if(MY_COMPILER_ID STREQUAL "GNU")
    message(STATUS "[my] GNU compiler: ${CMAKE_CXX_COMPILER}")
    # -fvisibility=hidden 默认让符号不可见
    # Set default visibility of all symbols to hidden
    set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
    set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE)
    ## -Wno-pedantic 禁用pedantic模式下的扩展警告
    ## -Wextra 额外严格警告
    set(MY_CXX_CMPL_OPTS_GCC -finput-charset=utf-8 -fexec-charset=utf-8 -Wall -Wextra -Wno-pedantic)
    list(JOIN MY_CXX_CMPL_OPTS_GCC " " MY_CXX_CMPILE_OPTIONS)

    list(JOIN MY_CXX_CMPL_OPTS_GCC "," MY_CUDA_CMPILE_OPTIONS)
    set(MY_CUDA_CMPILE_OPTIONS "-Xcompiler=${MY_CUDA_CMPILE_OPTIONS}")
    # message(STATUS "[my] MY_CUDA_CMPILE_OPTIONS => ${MY_CUDA_CMPILE_OPTIONS}")
endif()

# 为GCC编译器且为C++代码设置编译选项
# add_compile_options("$<$<AND:$<CXX_COMPILER_ID:GNU>,$<COMPILE_LANGUAGE:CXX>>:${MY_CXX_CMPILE_OPTIONS}>")
#xxxxxxxxxxxxxxxxxxxxxxxxx GPU, nvcc 设置; blackwell
#--------------- nvcc 选项, sync with cl, 但是分隔用 `,` 通过-Xcompiler传递
#add_compile_options("$<$<AND:$<CXX_COMPILER_ID:NVIDIA>,$<COMPILE_LANGUAGE:CUDA>>:${MY_CUDA_CMPILE_OPTIONS}>")

##xxxxxxxxxxxxxxxxxxx 告诉 NVCC 不要狗叫
if(CMAKE_CUDA_COMPILER AND TRUE)
    set(CUDA_WARNING_SUPPRESSIONS
        -diag-suppress=27   # 抑制fmt中的字符值超出范围警告
        -diag-suppress=128  # 抑制fmt中的"loop is not reachable"警告
        -diag-suppress=2417 # 抑制fmt中的constexpr构造函数警告
        -diag-suppress=1388 # 抑制spdlog中的DLL接口规范不一致警告
        -diag-suppress=1394 # 抑制spdlog中的DLL接口字段警告
    )
    list(JOIN CUDA_WARNING_SUPPRESSIONS " " CUDA_WARNING_SUPPRESSIONS)
    set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${CUDA_WARNING_SUPPRESSIONS}")
endif()

#xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx apply flags
##======================== https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_FLAGS.html
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_CXX_CMPILE_OPTIONS}")
message(STATUS "[my] CMAKE_CXX_FLAGS => ${CMAKE_CXX_FLAGS}")
##======================== link flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_CXX_CMPILE_OPTIONS}")

#----
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${MY_CUDA_CMPILE_OPTIONS}")
message(STATUS "[nvcc] CMAKE_CUDA_FLAGS => ${CMAKE_CUDA_FLAGS}")


##00000000000000000000000000000000000000000000000000000000000000000000000000000000000 my functions
##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx copy project dependent dlls to binary dir, windows
function(my_cp_dlls target)
    if(NOT WIN32)
        message(STATUS "[my] Skip, not in windows")
        return()
    endif()
    add_custom_command(TARGET ${target} POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_RUNTIME_DLLS:${target}> $<TARGET_FILE_DIR:${target}>
        COMMAND_EXPAND_LISTS
        COMMENT "Copying DLLs to build directory")
endfunction()


##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 定义一个函数来打印所有相关定义
function(my_prt_target_definitions target)
    if(NOT TARGET ${target})
        message(WARNING "目标 ${target} 不存在")
        return()
    endif()

    # 获取不同作用域的属性
    get_target_property(private_defs ${target} COMPILE_DEFINITIONS)
    get_target_property(public_defs ${target} INTERFACE_COMPILE_DEFINITIONS)
    get_target_property(imported_defs ${target} IMPORTED_CONFIGURATIONS) # 对于导入的目标

    message("目标 ${target} 的宏定义:")

    if(private_defs)
        message("  PRIVATE: ${private_defs}")
    endif()

    if(public_defs)
        message("  PUBLIC/INTERFACE: ${public_defs}")
    endif()

    # 处理生成器表达式（可能需要进一步处理）
    get_target_property(genex_defs ${target} COMPILE_DEFINITIONS$<$<CONFIG:DEBUG>:DEBUG>)
    if(genex_defs)
        message("  生成器表达式相关: ${genex_defs}")
    endif()
endfunction()

##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 配置 MSVC 的 RelWithDebInfo 模式
function(my_config_msvc_relwithdebinfo target_name)
    if(NOT TARGET ${target_name})
        message(WARNING "Target ${target_name} 不存在")
        return()
    endif()

    # 确保只在 MSVC 编译器下执行
    set(MY_REL_DEB_OPTS "/utf-8;/EHsc;/Zc:__cplusplus;/permissive-;/Od;/Zi;/DDEBUG;/UNDEBUG")
    list(JOIN MY_REL_DEB_OPTS_CUDA "," MY_REL_DEB_OPTS)
    # 针对 RelWithDebInfo 关闭优化，启用调试宏
    target_compile_options(${target_name} PRIVATE
        # c++ 选项: 禁用优化; 确保生成调试信息; 定义 DEBUG 宏; 取消 NDEBUG 宏
        "$<$<AND:$<CONFIG:RelWithDebInfo>,$<COMPILE_LANGUAGE:CXX>>:${MY_REL_DEB_OPTS}>" # C++: 合并所有选项
        "$<$<AND:$<CONFIG:RelWithDebInfo>,$<COMPILE_LANGUAGE:CUDA>>:-Xcompiler=${MY_REL_DEB_OPTS_CUDA}>" # CUDA: 合并所有选项
    )

    # 确保生成 PDB 文件
    target_link_options(${target_name} PRIVATE
        "$<$<CONFIG:RelWithDebInfo>:/DEBUG>" # 确保生成 PDB 文件
    )

    # 设置运行时库为 Debug 版本（可选，但可能影响 ABI）
    # 如需启用，取消下面的注释
    # set_property(TARGET ${target_name} PROPERTY
    #     MSVC_RUNTIME_LIBRARY "MultiThreadedDebug$<$<CONFIG:Debug>:Debug>"
    # )
endfunction()


##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 生成和配置, export header; 导出符号的头文件
include(GenerateExportHeader)
function(my_config_export_header target_name export_dir)
    # 参数检查
    if(NOT TARGET ${target_name})
        message(WARNING "Target ${target_name} not exist")
        return()
    endif()

    # 确保导出目录存在
    file(MAKE_DIRECTORY ${export_dir})

    # 确保导出目录已设置
    if(NOT export_dir)
        set(export_dir "${CMAKE_BINARY_DIR}/export_headers")
        message(STATUS "Non-exist export directory, use default: ${export_dir}")
    endif()

    # 设置导出头文件路径; PARENT_SCOPE 为了方便调用者使用 header 的路径
    set(${target_name}_EXPORTS "${export_dir}/${target_name}_export.h" PARENT_SCOPE)

    # 生成导出头文件
    generate_export_header(${target_name} EXPORT_FILE_NAME "${export_dir}/${target_name}_export.h")

    # 设置目标的包含目录
    target_include_directories(${target_name} PUBLIC
        $<BUILD_INTERFACE:${export_dir}>
        $<INSTALL_INTERFACE:include>
    )

    # 安装导出头文件
    install(FILES "${export_dir}/${target_name}_export.h" DESTINATION include)

endfunction()


##0000000000000000000000000000000000000000000000000000000000000000000000000 find_package
##xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# list(PREPEND CMAKE_PREFIX_PATH "${MY_THIRD_PARTY}/fmt/lib/cmake/fmt")
# list(PREPEND CMAKE_PREFIX_PATH "${MY_THIRD_PARTY}/spdlog/lib/cmake/spdlog")


##xxxxxxxxxxxxxxxxxxxxxxxxxxxxx fmt
find_package(fmt CONFIG REQUIRED)
# 打印 fmt 库的基本信息
message(STATUS "[fmt] fmt_VERSION: ${fmt_VERSION}")
# 打印 fmt::fmt 目标的详细信息
if(TARGET fmt::fmt AND TRUE)
    message(STATUS "[fmt] Target fmt::fmt exists")

    # 获取目标类型
    get_target_property(FMT_TARGET_TYPE fmt::fmt TYPE)
    message(STATUS "[fmt] fmt::fmt target type: ${FMT_TARGET_TYPE}")

    # 获取包含目录
    get_target_property(FMT_INCLUDE_DIRS fmt::fmt INTERFACE_INCLUDE_DIRECTORIES)
    message(STATUS "[fmt] fmt::fmt include directories: ${FMT_INCLUDE_DIRS}")

    # 获取链接库
    get_target_property(FMT_LINK_LIBRARIES fmt::fmt INTERFACE_LINK_LIBRARIES)
    message(STATUS "[fmt] fmt::fmt link libraries: ${FMT_LINK_LIBRARIES}")

    # 获取编译定义
    get_target_property(FMT_COMPILE_DEFINITIONS fmt::fmt INTERFACE_COMPILE_DEFINITIONS)
    message(STATUS "[fmt] fmt::fmt compile definitions: ${FMT_COMPILE_DEFINITIONS}")

    # 获取编译选项
    get_target_property(FMT_COMPILE_OPTIONS fmt::fmt INTERFACE_COMPILE_OPTIONS)
    message(STATUS "[fmt] fmt::fmt compile options: ${FMT_COMPILE_OPTIONS}")
else()
    message(STATUS "[fmt] skip print, target fmt::fmt vars")
endif()


##xxxxxxxxxxxxxxxxxxxxxxxxxxxxx spdlog
find_package(spdlog CONFIG REQUIRED)

# 打印 spdlog 库的基本信息
if(TARGET spdlog::spdlog AND TRUE)
    message(STATUS "[spdlog] Target spdlog::spdlog exists")

    # 获取目标类型
    get_target_property(SPDLOG_TARGET_TYPE spdlog::spdlog TYPE)
    message(STATUS "[spdlog] spdlog::spdlog target type: ${SPDLOG_TARGET_TYPE}")

    # 获取包含目录
    get_target_property(SPDLOG_INCLUDE_DIRS spdlog::spdlog INTERFACE_INCLUDE_DIRECTORIES)
    message(STATUS "[spdlog] spdlog::spdlog include directories: ${SPDLOG_INCLUDE_DIRS}")

    # 获取链接库
    get_target_property(SPDLOG_LINK_LIBRARIES spdlog::spdlog INTERFACE_LINK_LIBRARIES)
    message(STATUS "[spdlog] spdlog::spdlog link libraries: ${SPDLOG_LINK_LIBRARIES}")

    # 获取编译定义
    get_target_property(SPDLOG_COMPILE_DEFINITIONS spdlog::spdlog INTERFACE_COMPILE_DEFINITIONS)
    message(STATUS "[spdlog] spdlog::spdlog compile definitions: ${SPDLOG_COMPILE_DEFINITIONS}")

    # 获取编译选项
    get_target_property(SPDLOG_COMPILE_OPTIONS spdlog::spdlog INTERFACE_COMPILE_OPTIONS)
    message(STATUS "[spdlog] spdlog::spdlog compile options: ${SPDLOG_COMPILE_OPTIONS}")
else()
    message(STATUS "[spdlog] skip print, target spdlog::spdlog vars")
endif()


##xxxxxxxxxxxxxxxxxxxxxxxxxxxxx cuda
if(TRUE)
    find_package(CUDAToolkit REQUIRED)
endif()

# 打印 CUDA 的基本信息
if(CMAKE_CUDA_COMPILER AND TRUE)
    message(STATUS "[CUDA] CUDA compiler found: ${CMAKE_CUDA_COMPILER}")
    message(STATUS "[CUDA] CUDA toolkit directory: ${CMAKE_CUDA_TOOLKIT_ROOT_DIR}")
    message(STATUS "[CUDA] CUDA include directories: ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}")
    message(STATUS "[CUDA] CUDA host compiler: ${CMAKE_CUDA_HOST_COMPILER}")
    message(STATUS "[CUDA] CUDA standard libraries: ${CMAKE_CUDA_STANDARD_LIBRARIES}")

    # 获取 CUDA 版本信息
    if(DEFINED CMAKE_CUDA_COMPILER_VERSION)
        message(STATUS "[CUDA] CUDA compiler version: ${CMAKE_CUDA_COMPILER_VERSION}")
    endif()

    # 获取 CUDA 架构信息
    if(DEFINED CMAKE_CUDA_ARCHITECTURES)
        message(STATUS "[CUDA] CUDA architectures: ${CMAKE_CUDA_ARCHITECTURES}")
    endif()

    # 打印 CUDA 库信息
    message(STATUS "[CUDA] CUDA_LIBRARIES: ${CUDA_LIBRARIES}")

    # 检查特定 CUDA 库
    if(DEFINED CUDA_cudart_LIBRARY)
        message(STATUS "[CUDA] CUDA cudart library: ${CUDA_cudart_LIBRARY}")
    endif()

    if(DEFINED CUDA_cublas_LIBRARY)
        message(STATUS "[CUDA] CUDA cublas library: ${CUDA_cublas_LIBRARY}")
    endif()

    if(DEFINED CUDA_cufft_LIBRARY)
        message(STATUS "[CUDA] CUDA cufft library: ${CUDA_cufft_LIBRARY}")
    endif()

    if(DEFINED CUDA_cufft64_LIBRARY)
        message(STATUS "[CUDA] CUDA cufft64 library: ${CUDA_cufft64_LIBRARY}")
    endif()

    # 打印所有 CUDA 相关的变量
    if(FALSE)
        get_cmake_property(VAR_NAMES VARIABLES)
        foreach(VAR_NAME ${VAR_NAMES})
            if(VAR_NAME MATCHES "^CUDA_")
                message(STATUS "[CUDA] CUDA variable ${VAR_NAME}: ${${VAR_NAME}}")
            endif()
        endforeach()
    endif()

else()
    message(STATUS "[CUDA] skip print CUDA")
endif()


##xxxxxxxxxxxxxxxxxxxxxxxxxxxxx cnpy库. 读取 .npz 文件
find_package(cnpy CONFIG REQUIRED)


#  find_package(clipp CONFIG REQUIRED)
find_package(argparse REQUIRED)


##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx python
list(PREPEND CMAKE_PREFIX_PATH "C:/Users/tom/AppData/Local/Programs/Python/Python312")
find_package(Python COMPONENTS Interpreter Development Development.SABIModule)


##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx pybind11
find_package(pybind11 REQUIRED)
message(STATUS "[python] Python_EXECUTABLE -> ${Python_EXECUTABLE}")
message(STATUS "[python] Python3_SOABI: ${Python3_SOABI}")

##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx pytorch
##torch cmake folder
# 查找Torch安装目录的CMake代码
# 支持Windows和Linux平台
# 初始化Torch安装目录变量
if(FALSE)
    set(my_TORCH_PKG_DIR "")
    # 根据不同平台设置候选路径
    if(WIN32)
    ## Windows平台候选路径
        set(torch_candidate_paths
            "C:/cpplibs/libtorch"
            "$ENV{LOCALAPPDATA}/Programs/Python/Python312/Lib/site-packages/torch"
            # 增加Python常见版本路径
            "$ENV{LOCALAPPDATA}/Programs/Python/Python311/Lib/site-packages/torch"
        )
    elseif(UNIX AND NOT APPLE)
    ## Linux平台候选路径
        set(torch_candidate_paths
            "/usr/local/lib/python3.12/dist-packages/torch"
            "/usr/lib/python3/dist-packages/torch"
            "$ENV{HOME}/.local/lib/python3.12/site-packages/torch"
            "/usr/local/lib/python3.11/dist-packages/torch"
            "/usr/lib/python3.11/dist-packages/torch"
            "$ENV{HOME}/.local/lib/python3.11/site-packages/torch"
        )
    endif()
    ## 检查每个候选路径
    foreach(path IN LISTS torch_candidate_paths)
        if(EXISTS "${path}")
            set(my_TORCH_PKG_DIR "${path}")
            message(STATUS "Torch package directory found: ${my_TORCH_PKG_DIR}")
            break()
        endif()
    endforeach()

    ## 如果未找到，给出提示
    if(NOT my_TORCH_PKG_DIR)
        message(FATAL_ERROR "Torch CMake directory missing, please ensure PyTorch installed")
    endif()

    message(STATUS "[torch] CUDA_nvrtc_LIBRARY => ${CUDA_nvrtc_LIBRARY}")
    # set(TORCH_CUDA_ARCH_LIST "8.6")
    list(PREPEND CMAKE_PREFIX_PATH "${my_TORCH_PKG_DIR}/share/cmake")


    ##======== find pytorch
    find_package(Torch REQUIRED)
    message(STATUS "[torch] TORCH_INCLUDE_DIRS => ${TORCH_INCLUDE_DIRS}")
    message(STATUS "[torch] TORCH_LIBRARIES => ${TORCH_LIBRARIES}")
    message(STATUS "[torch] TORCH_CXX_FLAGS => ${TORCH_CXX_FLAGS}")
    message(STATUS "[torch] Caffe2_MAIN_LIBS => ${Caffe2_MAIN_LIBS}")
    message(STATUS "[torch] CAFFE2_INCLUDE_DIRS => ${CAFFE2_INCLUDE_DIRS}")
    message(STATUS "[torch] ATEN_INCLUDE_DIR => ${ATEN_INCLUDE_DIR}")
    message(STATUS "[torch] ATEN_LIBRARIES => ${ATEN_LIBRARIES}")

    get_target_property(tmpl torch INTERFACE_LINK_LIBRARIES)
    message(STATUS "[torch] torch.INTERFACE_LINK_LIBRARIES ->${tmpl}")

    get_target_property(tmpl torch_cpu_library INTERFACE_LINK_LIBRARIES)
    message(STATUS "[torch] torch_cpu_library.INTERFACE_LINK_LIBRARIES ->${tmpl}")

    get_target_property(tmpl torch_cuda_library INTERFACE_LINK_LIBRARIES)
    message(STATUS "[torch] torch_cuda_library.INTERFACE_LINK_LIBRARIES ->${tmpl}")

    ##======================================
    set(CMAKE_CUDA_ARCHITECTURES native)
    message(STATUS "[torch] CMAKE_CUDA_FLAGS ->${CMAKE_CUDA_FLAGS}")
    message(STATUS "[torch] CMAKE_CUDA_ARCHITECTURES => ${CMAKE_CUDA_ARCHITECTURES}")
endif()